import React, { useState, useEffect, useLayoutEffect, useRef, useImperativeHandle } from "react";
import { Button } from "antd";
/**
 * 类组件中，我们基于ref可以做的事情：
 *  1. 赋值给一个标签：获取DOM元素
 *  2. 赋值给一个类自组件：获取子组件实例[可以基于实例调用子组件中的属性和方法等]
 *  3. 赋值给一个函数子组件：报错[需要配合React.forwardRef实现Ref转发，获取子组件中的某一个DOM元素]
 * 
 * ref的使用方法：
 * 1. ref='box'
 *    this.refs.box【不推荐使用】
 * 2. ref={x=>this.box=x}
 *    this.box 获取
 * 3. this.box=React.createRef()创建一个ref对象<h2 ref={this.box}></h2> this.box.current 获取DOM元素
 * 
 */

/*
//基于ref获取子组件的实例，这样基于实例可以调用子组件内部挂载到实例上的东西
class Child extends React.Component{
    state = {
        x:100
    }

    render(){
        return <div className="child-box">
            {this.state.x}
        </div>
    }
} */
//基于forwardRef实现ref转发：目的：获取子组件内部的某个元素
/* const Child = React.forwardRef(function Child(props,ref){
    return <div className="child-box">
        <span ref={ref}>1</span>
    </div>
}
) */
//函数子组件内部，可以有自己的状态和方法了；如何实现：基于forwardRef实现ref转发的同时，获取函数子组件内部的状态或者方法呢？=>useImperativeHandle
const Child = React.forwardRef(function Child(props, ref) {
    let [text, setText] = useState('你好世界')
    let submit = () => { }
    useImperativeHandle(ref, () => {
        //在这里返回的内容，都可以被父组件的ref对象获取到
        return {
            text,
            submit
        }
    })
    return <div className="child-box">
        <span ref={ref}>1</span>
    </div>
})

function Demo(props) {
    let [num, setNum] = useState(0);
    let box1 = useRef(null);

    useEffect(() => {
        console.log(box1.current);
    }, [])
    return <div>
        <Child ref={box1} />
    </div>
}
export default Demo